package gbench.appdemo.mall.erp.components;

import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.tree.LittleTree.Term.FT;

import java.util.List;

import gbench.appdemo.mall.erp.MyERPApp.InboundBill;
import gbench.appdemo.mall.erp.MyERPApp.OutboundBill;
import gbench.common.matlib.data.DataReader.DFrame;
import gbench.common.tree.LittleTree.IRecord;

/**
 * 
 * @author gbench
 *
 */
public interface IStore extends IMyERPEntity {

    /**
     * 
     * @return
     */
    public Integer getId();

    /**
     * 产品名称
     * 
     * @return
     */
    public String getName();

    /**
     * 初始化仓库
     */
    public void initialize();

    /**
     * 添加库房
     * 
     * @param house
     */
    public void addWareHouse(IWareHouse house);
    
    public IWareHouse createHouse(final IRecord rec);

    /**
     * 
     * @return
     */
    public List<IWareHouse> getHouses();

    /**
     * 
     * @return
     */
    public IWareHouse getDefaultWareHouse();
    
    public void addHouse(IWareHouse house);
    
    /**
     * 
     * @return
     */
    public IEnterprise getOwner();
    
    /**
     * 入库: 在 t_entity_item_rel 表中插入一条数据。 name:t_house/t_product
     * 
     * @param product 入库产品
     * @param amount 入库数量
     */
    public default void inbound(IProduct product, Double quantity,Integer orderId, IWareHouse house) {
        if(house==null) {
            println("库房为空,无法出产品入库");
            return;
        }
        final var dataApp = this.dataApp();
        
        // 此处 把 amount 位置用于存储 入库的 owner id
        dataApp.rel2insert("t_house" /*entity_tbl*/, "t_product" /*item_tbl*/, house.getId() /*entity_id*/, product.getId() /*item_id*/, 
                0 /*drcr*/, quantity /*quantity*/, 0 /*flag*/, 0 /*amount*/, this.getOwner().getId() /*ref*/, orderId /*optional*/, 
                FT("$0#$1[入库]$2",this.getOwner().getId(),this.getOwner().getName(),product.getName()) /*description*/);
    }

    /**
     * 入库
     * 
     * @param product 产品入库
     * @param amount 入库数量
     */
    public default void inbound(IProduct product, Double quantity,Integer orderId) {
        this.inbound(product, quantity,orderId, this.getDefaultWareHouse());
    }
    
    /**
     * 产品入库
     * @param inbound 入库单
     */
    public default void inbound(InboundBill inbound) {
        final var id = inbound.getOrder().getId();
        inbound.getLineItems().forEach(e->{
            this.inbound(e.getProduct(), e.getQuantity(),id);
        });
    }
    
    /**
     * 出库
     * 
     * @param product 出库产品
     * @param quantity 出库数量
     * @param orderId 销售订单
     * @param house 出库库房
     */
    public default void outbound(final IProduct product, final Double quantity, final Integer orderId,final IWareHouse house) {
        if(house==null) {
            println("库房为空,无法出产品出库");
            return;
        }
        
        final var dataApp = this.dataApp();
        
        // 此处 把 amount 位置用于存储 入库的 owner id
        dataApp.rel2insert("t_house" /*entity_tbl*/, "t_product" /*entity_tbl*/, house.getId() /*entity_id*/, product.getId() /*item_id*/, 
            1 /*drcr*/, quantity /*quantity*/,0 /*flag*/, 0 /*amount*/, this.getOwner().getId() /*ref*/, orderId /*optional*/, 
            FT("$0#$1[出库]$2",this.getOwner().getId(),this.getOwner().getName(),product.getName()) /*description*/);
    }

    /**
     * 出库
     * 
     * @param product 产品对象
     * @param amount 入库数量
     * @param orderId 销售订单编号
     */
    public default void outbound(final IProduct product, final Double amount,Integer orderId) {
        this.outbound(product, amount, orderId,this.getDefaultWareHouse());
    }
    
    /**
     * 产品出库
     * @param outbound 出库单
     */
    public default void outbound(OutboundBill outbound) {
        final var id = outbound.getOrder().getId();
        outbound.getLineItems().forEach(e->{
            this.outbound(e.getProduct(), e.getQuantity(),id);
        });
    }
    
    /**
     * 试算平衡表
     * @return
     */
    public default DFrame trialBalance() {
        
        return this.trialBalance(this.getDefaultWareHouse());
    }
    
    /**
     * 试算平衡表
     * @return
     */
    public default DFrame trialBalance(IWareHouse house) {
        if(null==house) {
            println("库房为空不予试算！");
            return null;
        }
        println(FT("$0-$1-试算平衡",this.getName(),house.getName()));
        return house.trialBalance();
    }

}
